﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;

namespace UFrame
{
    public static class ABVersion
    {
        public static string versionFilePath = string.Empty;

        private static List<string> versionLines = new List<string>();
        private static List<string> abNameList;                            //选择的ab打包文件

        private static string versionTxT = "Version.txt";

        static ABVersion()
        {
            versionFilePath = Path.Combine(ABPath.GetPath(), versionTxT);
        }

        public static void BuildVersion(List<string> abNameList = null)
        {
            Caching.ClearCache();
            ABVersion.abNameList = abNameList;
            CreateUpdateTXT();
        }

        // 创建更新文本
        private static void CreateUpdateTXT()
        {
            string[] allFile = Directory.GetFiles(ABPath.GetPath(), "*.*", SearchOption.AllDirectories);
            List<string> buildABFile = new List<string>();
            bool selectBuildAB = false;
            if (abNameList == null)
            {
                buildABFile = allFile.ToList();
                selectBuildAB = false;
            }
            else
            {
                //选择打那些AB包，然后计算MD5值 修改原来的version.Txt
                foreach (var filePath in allFile)
                {
                    for (int i = 0; i < abNameList.Count; i++)
                    {
                        string selectAB = abNameList[i].ToLower();
                        string fileName = filePath.Substring(ABPath.GetPath().Length);
                        if (selectAB == fileName || (selectAB + ".manifest") == fileName)
                        {
                            buildABFile.Add(filePath);
                            break;
                        }
                    }
                }

                ReadVersionTXT(versionFilePath);
                selectBuildAB = true;
            }


            StringBuilder stringBuilder = new StringBuilder();
            foreach (string filePath in buildABFile)
            {
                int size = 0;
                string md5 = BuildFileMd5(filePath, out size);
                string fileName = filePath.Substring(ABPath.GetPath().Length);
                string newLineInfo = string.Format("{0}:{1}:{2}", fileName, md5, size);

                if (selectBuildAB)
                {
                    for (int i = 0; i < versionLines.Count; i++)
                    {
                        var versionLine = versionLines[i].Split(':');
                        string lineABName = versionLine[0];
                        string lineABMD5 = versionLine[1];
                        if (lineABName == fileName)
                        {
                            versionLines[i] = newLineInfo;
                            break;
                        }
                        else if (i == versionLines.Count - 1)
                        {
                            versionLines.Add(newLineInfo);
                        }
                    }
                }
                else
                {
                    stringBuilder.AppendLine(newLineInfo);
                }
            }

            if (selectBuildAB)
            {
                foreach (var item in versionLines)
                {
                    stringBuilder.AppendLine(item);
                }
            }

            WriteTXT(versionFilePath, stringBuilder.ToString());
        }

        private static string BuildFileMd5(string filePath, out int size)
        {
            size = 0;
            string fileMd5 = string.Empty;
            try
            {
                using (FileStream fs = File.OpenRead(filePath))
                {
                    MD5 md5 = MD5.Create();
                    byte[] fileMd5Bytes = md5.ComputeHash(fs); // 计算FileStream 对象的哈希值
                    fileMd5 = BitConverter.ToString(fileMd5Bytes).Replace("-", "").ToLower();
                    size = fileMd5Bytes.Length * 128;
                }
            }
            catch (Exception ex)
            {
                Debug.LogError(ex);
            }

            return fileMd5;
        }

        public static void WriteTXT(string path, string content)
        {
            string directory = Path.GetDirectoryName(path);
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            if (File.Exists(path))
            {
                File.Delete(path);
            }

            using (FileStream fs = File.Create(path))
            {
                StreamWriter sw = new StreamWriter(fs, Encoding.Unicode);
                try
                {
                    sw.Write(content);
                    sw.Close();
                    fs.Close();
                    fs.Dispose();
                }
                catch (IOException e)
                {
                    Debug.Log(e.Message);
                }
            }
        }

        private static void ReadVersionTXT(string path)
        {
            string directory = Path.GetDirectoryName(path);
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            versionLines.Clear();
            if (File.Exists(path))
            {
                string[] lines = File.ReadAllLines(path,Encoding.UTF8);
                versionLines = lines.ToList();
            }
        }
    }
}